print('Lua Rocks! Rrrrrrr-ocks!')

mouseleft = 0
mousx = 0
mousy = 0
oldmousx = 0
oldmousy = 0
xres = 0
yres = 0
numframes = 0
deltatime = 0
time = 0
enemySpawnTime = 0

lastShotTime = 0

enemies = {}
particles = {}
shooters = {}
bullets = {}

function printf(fmt, ...)
  io.write(string.format(fmt, ...))
end

Enemy = {}
Enemy.size = 40
function makeEnemy(x,y)
  local _ = {}
  _.x = x
  _.y = y
  _.life = 1.0
  _.dead = false
  _.anim_frame = 0
  _.anim_time = 0.0
  return _
end

Shooter = {}
function Shooter.new(x,y)
  local info = {}
  info.x = x
  info.y = y
  info.angle = 0
  return info
end

Bullet = {}
Bullet.size = 8
function Bullet.new(x,y,dx,dy)
  local info = {}
  info.x = x
  info.y = y
  info.dx = dx
  info.dy = dy
  info.dead = false
  return info  
end

Color = {}
local colorsmeta = {}
function Color.new(r,g,b)
  local info = {}
  info.r = r
  info.g = g
  info.b = b
  setmetatable(info, colorsmeta)
  return info
end

Particle = {}
local particlemeta = {}
function Particle.new(x,y)
  local info = {}
  info.x = x
  info.y = y
  info.dx = math.random(50)-25
  info.dy = math.random(50)-25
  info.color = Color.new(192+math.random(64),64+math.random(64),0 )
  info.life = 0.8
  --setmetatable(info, particlemeta )
  return info
end

function foo() 
  print('function foo()')
  print('xres=' .. xres .. ' yres=' .. yres )
  print('shooterx '..shooters[1].x )
   toggle() 
end

function drawShooter(s)
  local sizeX = 50
  local halfSizX = sizeX / 2.0
  local len = 25
  
  drawline( s.x, s.y, s.x + math.cos(s.angle)*len, s.y + math.sin(s.angle)*len)
  drawRect( s.x - halfSizX, s.y, sizeX, halfSizX )
end 

function dist(x1,y1,x2,y2)
  return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)
end 

function setup()
  print('setup')
  print('making shooter...')
  table.insert( shooters, Shooter.new( xres/2, yres-26 ))
  math.randomseed( os.time() )
end

function draw() 
  time = time + deltatime

  DrawParticles()
  DoBullets()
  DoEnemies()
  drawShooter( shooters[1] )
  
  if numframes % 5 == 0 then
  CheckCollisions()
  end
  
  setcolor(255,255,255)
  bmxprintf(10, 10, "numframes " .. numframes)
  bmxprintf(10, 20, "dt: " .. deltatime)
  bmxprintf(10, 30, "particles: " .. #particles)
  bmxprintf(10, 40, "bullets: " .. #bullets)
  bmxprintf(10, 50, "enemies: " .. #enemies)
  shooters[1].angle = math.atan2( mousy-shooters[1].y, mousx-shooters[1].x )
  
  
  -- spawn new enemy
  if( time > enemySpawnTime ) then
    enemySpawnTime = time + 3
    table.insert(enemies, makeEnemy(-10, math.random(10,130) ) )
  end
  
  Input()
  
  oldmousx = mousx
  oldmousy = mousy
  numframes = numframes + 1
end

function DoBullets()
  local deadBulletIndices = {}
  setcolor(255,0,0)
  for i,v in pairs(bullets) do
    drawsph( v.x, v.y, Bullet.size )

    table.insert(particles,
    Particle.new( v.x + math.random(10) -5, v.y + math.random(10) -5  ))
    
    v.x = v.x + v.dx * 200 * deltatime
    v.y = v.y + v.dy * 200 * deltatime
    
    if( v.x < 0 or v.x > xres or v.y < 0 or v.y > yres) then
      table.insert(deadBulletIndices, i)
    elseif v.dead then
      table.insert(deadBulletIndices, i)
    end
  end
  
  for i=1, #deadBulletIndices do
    k = deadBulletIndices[i]
    table.remove(bullets,k)
  end
end 

function DrawParticles()
  local deadParticles = {}
  for i,v in pairs(particles) do
    setcolor( v.color.r * v.life, v.color.g * v.life , v.color.b * v.life )
    alphaparticle(v.x,v.y)
    --drawsph( v.x, v.y, 5 )
    
    v.x = v.x + v.dx * deltatime
    v.y = v.y + v.dy * deltatime
    
    v.life = v.life - deltatime
    if( v.life <= 0.0) then
      table.insert(deadParticles, i)
    end  
  end
  
  for i=1, #deadParticles do
    k = deadParticles[i]
    table.remove(particles,k)
  end
end

function DoEnemies()
  
  local deadEnemyIndices = {}
   
  setcolor(255,255,255)
  for i,v in pairs(enemies) do
    if( v.dead == false ) then
      drawAnimSprite(v.x, v.y, "flue_right.png", 32, 32, 5, v.anim_frame)
    else
      drawAnimSprite(v.x, v.y, "flue_right.png", 32, 32, 5, 4)
    end
    
    
    if( v.anim_time < time ) then 
      v.anim_time = time + 0.05
      v.anim_frame = v.anim_frame + 1
      if( v.anim_frame >= 3 ) then
        v.anim_frame = 0
      end
    end
    --drawsprite(v.x, v.y, "flue.png")
    --drawsph(v.x,v.y,Enemy.size)
    
    v.x = v.x + 250 * deltatime
    if( v.x > (xres+Enemy.size) ) then v.x = -Enemy.size end
    
    if v.dead == true then
       table.insert(particles,
    Particle.new( v.x + math.random(10) -5, v.y + math.random(10) -5  ))
    
      v.x = v.x + math.random(-5,5) * deltatime
      v.y = v.y + 150 * deltatime
      if( v.y > (yres+Enemy.size) ) then
        table.insert(deadEnemyIndices, i)
      end
    end
  end
  
  for i=1, #deadEnemyIndices do
    k = deadEnemyIndices[i]
    table.remove(enemies,k)
  end 
end

function CheckCollisions()
  local enemySizeSq = Enemy.size*Enemy.size
  local bulletSizeSq = Bullet.size*Bullet.size
  for i, b in pairs(bullets) do
    for j, e in pairs(enemies) do
      if(e.dead == false) then
        if( dist(b.x,b.y,e.x,e.y) < enemySizeSq+bulletSizeSq ) then
          e.life = -1.0
          e.dead = true
          b.dead = true
          
          for k = 1, 100 do
            local x = math.cos( k*2*math.pi / 99 )*Enemy.size/2
            local y = math.sin( k*2*math.pi / 99 )*Enemy.size/2
            table.insert(particles,Particle.new( x+b.x + math.random(-10.0, 10.0), y+b.y + math.random(-10.0, 10.0) ))
          end 
        end
      end
    end
  end
end

function Input()
  if mouseleft == 1 and time>lastShotTime then
    lastShotTime = time + .1 -- 100 ms between shots
    local ca = math.cos(shooters[1].angle)
    local sa = math.sin(shooters[1].angle)
    local b = Bullet.new( shooters[1].x+ca*25, shooters[1].y+sa*25, ca, sa )
    table.insert(bullets, b)
  end
end